#include <windows.h>
#include<stdio.h>
#include "resource.h"

int check=1;
int cancel=0;
 
HWND graf=NULL;
int head,tail;
int q[11];
int nr=0;
int m[9][9]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
int contor=0;
int minim (int x, int y) {
    return x<y ? x : y; 
}

#define NN 1024

// adjacency matrix (fill this up)
int cap[NN][NN];

// flow network
int fnet[NN][NN];

// BFS
int q1[NN], qf, qb, prev[NN];

int fordFulkerson( int n, int s, int t )
{
    // init the flow network
    memset( fnet, 0, sizeof( fnet ) );

    int flow = 0;

    while( true )
    {
        // find an augmenting path
        memset( prev, -1, sizeof( prev ) );
        qf = qb = 0;
        prev[q1[qb++] = s] = -2;
        while( qb > qf && prev[t] == -1 )
            for( int u = q1[qf++], v = 0; v < n; v++ )
                if( prev[v] == -1 && fnet[u][v] - fnet[v][u] < m[u][v] )
                    prev[q1[qb++] = v] = u;

        // see if we're done
        if( prev[t] == -1 ) break;

        // get the bottleneck capacity
        int bot = 0x7FFFFFFF;
        for( int v = t, u = prev[v]; u >= 0; v = u, u = prev[v] )
            bot = minim(bot,m[u][v] - fnet[u][v] + fnet[v][u]);

        // update the flow network
        for( int v = t, u = prev[v]; u >= 0; v = u, u = prev[v] )
            fnet[u][v] += bot;

        flow += bot;
    }

    return flow;
}

int v[9];
int b=0;
char s[10];
int h;
int o;
int p;
int f;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	int c1=1,c2=1;
	switch(Message)
    {
		
        case WM_INITDIALOG:
			
        return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDOK:
					cancel=0;
					BOOL bSuccess;
					BOOL cSuccess;
					BOOL dSuccess;
					h=GetDlgItemInt(hwnd,IDC_EDIT3,&dSuccess,1);
					p=GetDlgItemInt(hwnd, IDC_EDIT1, &bSuccess, 1);
					o=GetDlgItemInt(hwnd, IDC_EDIT2, &cSuccess, 1);
					if(bSuccess && cSuccess && dSuccess)
						if(!m[p-1][h-1])
							if(p-1!=h-1)
						{
							cancel=1;
							
							m[h-1][p-1]=o;
							if(m[h-1][p-1] )
							for(f=0;f<=contor;f++)
								{
									if(v[f]==h)
										c1=0;
									
									if(v[f]==p)
										c2=0;
							}

									if(c1)
									{
										v[contor]=h;
										contor++;
									}
							
									
									if(c2)
									{
										v[contor]=p;
										contor++;
									}
									c1=1;
									c2=1;
							
							
					}
                    EndDialog(hwnd, IDOK);
                break;
                case IDCANCEL:
					cancel=0;
                    EndDialog(hwnd, IDCANCEL);
                break;
            }
        break;
		
        default:
            return FALSE;
    }
    return TRUE;
	    
}
int sursa=0;
int destinatie=0;
BOOL CALLBACK AboutDlgProc2(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	
	int i,j;
	switch(Message)
    {
		
        case WM_INITDIALOG:
			
        return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDOK:
					
					BOOL bSuccess;
					BOOL cSuccess;
					i=GetDlgItemInt(hwnd, IDC_EDIT4, &bSuccess, 1);
					j=GetDlgItemInt(hwnd, IDC_EDIT5, &cSuccess, 1);
					if(bSuccess && cSuccess)
					{
						sursa=i;
						destinatie=j;
					}
                    EndDialog(hwnd, IDOK);
                break;
                case IDCANCEL:
                    EndDialog(hwnd, IDCANCEL);
                break;
            }
        break;
		
        default:
            return FALSE;
    }
    return TRUE;
	
    
}
 
 int ok1=0;
  int ok2=0;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  HDC hdc=NULL;
  HPEN hPen[9];ACTCTX_FLAG_SET_PROCESS_DEFAULT;
  PAINTSTRUCT ps;
  int k=0;
  int ok=0;
  int i,j;
  char flow[10];
  char l[10];
  int g=0;
  int flux=0;
  HPEN hpen;
  hdc=GetDC(hwnd);
  hpen=CreatePen(PS_SOLID,300,RGB(255,255,255));
  switch(msg)  
  {
	  case WM_CREATE:
	{
           CreateWindow(TEXT("button"), TEXT("Legatura Noua"),    
		             WS_VISIBLE | WS_CHILD ,
		             30, 400, 120, 25,        
		             hwnd, (HMENU) 1, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Calculeaza"),    
		             WS_VISIBLE | WS_CHILD ,
		             400, 400, 120, 25,        
		             hwnd, (HMENU) 4, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Sursa si Destinatia"),    
		             WS_VISIBLE | WS_CHILD ,
		             250, 400, 140, 25,        
		             hwnd, (HMENU) 3, NULL, NULL);
		   CreateWindow(TEXT("button"), TEXT("Quit"),    
		             WS_VISIBLE | WS_CHILD ,
		             160, 400, 80, 25,        
		             hwnd, (HMENU) 2, NULL, NULL);  
		   CreateWindow(TEXT("button"), TEXT("Refresh"),    
		             WS_VISIBLE | WS_CHILD ,
		             30, 430, 120, 25,        
		             hwnd, (HMENU) 5, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Help"),    
		             WS_VISIBLE | WS_CHILD ,
		             160, 430, 80, 25,        
		             hwnd, (HMENU) 6, NULL, NULL);
		   
			CreateWindowEx(WS_EX_CLIENTEDGE, "EDTI",NULL,WS_CHILD | WS_VISIBLE,450,300,80,80,
									hwnd,(HMENU)IDC_MAIN_LIST,GetModuleHandle(NULL),NULL);
			SendDlgItemMessage(hwnd, IDC_MAIN_LIST, LB_ADDSTRING,0,(LPARAM)"");
		   
	    break;
	}

      case WM_COMMAND:
      {
		  switch(LOWORD(wParam))
		  {
		  case 5:
			  
			  SelectObject(hdc,hpen);
			  Rectangle(hdc,0,0,600,500);
			  CreateWindow(TEXT("button"), TEXT("Legatura Noua"),    
		             WS_VISIBLE | WS_CHILD ,
		             30, 400, 120, 25,        
		             hwnd, (HMENU) 1, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Calculeaza"),    
		             WS_VISIBLE | WS_CHILD ,
		             400, 400, 120, 25,        
		             hwnd, (HMENU) 4, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Sursa si Destinatia"),    
		             WS_VISIBLE | WS_CHILD ,
		             250, 400, 140, 25,        
		             hwnd, (HMENU) 3, NULL, NULL);
		   CreateWindow(TEXT("button"), TEXT("Quit"),    
		             WS_VISIBLE | WS_CHILD ,
		             160, 400, 80, 25,        
		             hwnd, (HMENU) 2, NULL, NULL);  
		   CreateWindow(TEXT("button"), TEXT("Refresh"),    
		             WS_VISIBLE | WS_CHILD ,
		             30, 430, 120, 25,        
		             hwnd, (HMENU) 5, NULL, NULL); 
		   CreateWindow(TEXT("button"), TEXT("Help"),    
		             WS_VISIBLE | WS_CHILD ,
		             160, 430, 80, 25,        
		             hwnd, (HMENU) 6, NULL, NULL);
		   for(i=0;i<contor;i++)
			   v[i]=0;
			  for(i=0;i<9;i++)
				  for(j=0;j<9;j++)
					  m[i][j]=0;
			  b=0;
			  g=0;
			  sursa=0;
			  destinatie=0;
			  break;
		  case 6:
			  MessageBox(hwnd,"Acesta este o aplicatie care calculeaza fluxul maxim.\n\n\nPentru introducerea unei noi legaturi apasati <<Legatura Noua>>\n\nPentru a iesi apasati <<Quit>>\n\nPentru a selecta o sursa si o destinatie apasati <<Sursa si Destinatie>>\n\nPentru a calcula fluxul maxim apasati <<Calculeaza>>\n\nPentru reimprospatarea ferestrei apasati <<Refresh>>","Help",MB_OK);
		  break;
		  case 4:
		 {
			 if(sursa && destinatie)
			 {

				 memset( cap, 0, sizeof( cap ) );
				 flux=fordFulkerson( contor, sursa-1, destinatie-1 );
			 //flux=max_flow(sursa-1,destinatie-1);
			itoa(flux,flow,10);
			TextOut(hdc,30,350,"Fluxul Maxim = : ",15); 
			TextOut(hdc,130,350,flow,2);
			 }
			 else
				 MessageBox(hwnd,"Introduceti o sursa si o destinatie","Eroare",MB_OK);
			break;
		 }	
			
		  case 1:
			  int ln;
			  ln=DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DIALOG3), hwnd, AboutDlgProc);
			 
			 // hdc=GetDC(hwnd);
			  if(ln && m[h-1][p-1]!=0 && cancel)
			  {
				itoa(h,s,10);
				TextOut(hdc, 450+g*20,42.5+b*20,s,1) ;
				g++;
				TextOut(hdc,450+g*10,42.5+b*20," -> ",4);
				g++;
				itoa(p,s,10);
				TextOut(hdc, 450+g*15,42.5+b*20,s,1) ;
				g++;
				TextOut(hdc,430+g*20,42.5+b*20," = ",3);
				g++;
				itoa(o,s,10);
				TextOut(hdc, 430+g*20,42.5+b*20,s,2) ;
				b++;
			    g=0;
			  }
			  
			   for(i=0;i<9;i++)
				{
					check=1;
					for(j=0;j<8;j++)
						if(m[i][j]!=0)
							for(int w=j+1;w<9;w++)
								
								if(i==w)
									check=0;
					if(check)
						nr++;
				}		
		  					
		  for(i=0;i<9;i++)
			  for(j=0;j<9;j++)
				  if(m[i][j]!=0)
				  {
					  if(i<=2)
					  {
						
						Ellipse(hdc, 30+i*140, 30, 70+i*140,70); 
						itoa(i+1,l,10);
						TextOut(hdc, 45+i*140,42.5,l,1) ;
						if(j<3)
						{

							itoa(j+1,l,10);
							Ellipse(hdc, 30+j*140, 30, 70+j*140,70);
							TextOut(hdc, 45+j*140,42.5,l,1) ;
							MoveToEx(hdc, 70+i*140, 50, NULL);
							LineTo(hdc,30+j*140,50);
							
						}
						else
							if(j<6)
							{
								if(j==3)
								{
									k=0;

									itoa(j+1,l,10);
									Ellipse(hdc, 30+k*140, 130, 70+k*140,170);
									TextOut(hdc, 45+k*140,42.5+100,l,1) ;
									MoveToEx(hdc, 70+i*140, 50, NULL);
									LineTo(hdc,30+k*140,150);

								}
								if(j==4)
								{
									k=1;

									itoa(j+1,l,10);
									Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
									TextOut(hdc, 45+k*140,42.5+100,l,1) ;
									MoveToEx(hdc, 70+i*140, 50, NULL);
									LineTo(hdc,30+k*140,150);

								}
								if(j==5)
								{
									k=2;
									itoa(j+1,l,10);
									Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
									TextOut(hdc, 45+k*140,42.5+100,l,1) ;
									MoveToEx(hdc, 70+i*140, 50, NULL);
									LineTo(hdc,30+k*140,150);

								}
							}
							else
								if(j<9)
								{
									if(j==6)
									{
										k=0;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
										TextOut(hdc, 45+k*140,42.5+200,l,1) ;
										MoveToEx(hdc, 70+i*140, 50, NULL);
										LineTo(hdc,30+k*140,250);
									}
									if(j==7)
									{
										k=1;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
										TextOut(hdc, 45+k*140,42.5+200,l,1) ;
										MoveToEx(hdc, 70+i*140, 50, NULL);
										LineTo(hdc,30+k*140,250);
									}
									if(j==8)
									{
										k=2;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 230, 70+k*140,270);
										TextOut(hdc, 45+k*140,42.5+200,l,1) ;
										MoveToEx(hdc, 70+i*140, 50, NULL);
										LineTo(hdc,30+k*140,250);
									}
								}
					  }
					  else
						  if(i<6)
						  {

							  itoa(i+1,l,10);
							  Ellipse(hdc, 30+(i-3)*140, 130, 70+(i-3)*140,170); 
							  TextOut(hdc, 45+(i-3)*140,42.5+100,l,1) ;
							   MoveToEx(hdc, 70, 50, NULL);
							  if(j<3)
								{

									itoa(j+1,l,10);
									Ellipse(hdc, 30+j*140, 30, 70+j*140,70);
									TextOut(hdc, 45+j*140,42.5,l,1) ;
									MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
									LineTo(hdc,30+j*140,50);
								}
							  else
								if(j<6)
								{
									if(j==3)
									{
										k=0;

										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170);
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
										LineTo(hdc,30+k*140,150);
									}
									if(j==4)
									{
										k=1;

										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
										LineTo(hdc,30+k*140,150);
									}
									if(j==5)
									{
										k=2;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
										LineTo(hdc,30+k*140,150);
									}
								}
						  
								else
									if(j<9)
									{
										if(j==6)
										{
											k=0;

											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270);
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
											LineTo(hdc,30+k*140,250);
										}
										if(j==7)
										{
											k=1;
											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
											LineTo(hdc,30+k*140,250);
										}
										if(j==8)
										{
											k=2;
											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-3)*140, 150, NULL);
											LineTo(hdc,30+k*140,250);
										}
									}
						  }
							 else
								 if(i<9)
								 {
									 itoa(i+1,l,10);
									 Ellipse(hdc, 30+(i-6)*140, 230, 70+(i-6)*140,270); 
									 TextOut(hdc, 45+(i-6)*140,42.5+200,l,1) ;
									 MoveToEx(hdc, 70, 50, NULL);
									 if(j<3)
										{
											itoa(j+1,l,10);
											Ellipse(hdc, 30+j*140, 30, 70+j*140,70); 
											TextOut(hdc, 45+j*140,42.5,l,1) ;
											MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
											LineTo(hdc,30+j*140,50);
										}
									else
								if(j<6)
								{
									if(j==3)
									{
										k=0;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
										LineTo(hdc,30+k*140,150);
									}
									if(j==4)
									{
										k=1;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
										LineTo(hdc,30+k*140,150);
									}
									if(j==5)
									{
										k=2;
										itoa(j+1,l,10);
										Ellipse(hdc, 30+k*140, 130, 70+k*140,170); 
										TextOut(hdc, 45+k*140,42.5+100,l,1) ;
										MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
										LineTo(hdc,30+k*140,150);
									}
								}
						  
								else
									if(j<9)
									{
										if(j==6)
										{
											k=0;
											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
											LineTo(hdc,30+k*140,250);
										}
										if(j==7)
										{
											k=1;
											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270);
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
											LineTo(hdc,30+k*140,250);
										}
										if(j==8)
										{
											k=2;
											itoa(j+1,l,10);
											Ellipse(hdc, 30+k*140, 230, 70+k*140,270); 
											TextOut(hdc, 45+k*140,42.5+200,l,1) ;
											MoveToEx(hdc, 70+(i-6)*140, 250, NULL);
											LineTo(hdc,30+k*140,250);
										}
									}
								 }
						 }
			
		
		//ReleaseDC(hwnd,hdc);		
		    break;

			case 3:
				 int sd;
				 sd=DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DIALOG4), hwnd, AboutDlgProc2);
				 for(int z=0;z<contor;z++)
					 {
						 if(sursa==v[z] || sursa==v[z])
							 ok1=1;
							 if(destinatie==v[z] ||destinatie==v[z])
								 ok2=1;
						 }
				 if(!ok1 || !ok2)
				 {
					 MessageBox(hwnd,"Ati introdus o sursa sau o destinatie care nu apartin grafului","Eroare",MB_OK);
					 sursa=0;
					 destinatie=0;
				 }
				 else
					 if(sd)
				 {
					 itoa(sursa,s,10);
					 TextOut(hdc,30,300,"Sursa = ",8);
					 TextOut(hdc, 80,300,s,strlen(s));
					 itoa(destinatie,s,10);
					 TextOut(hdc,200,300,"Destinatie = ",13);
					 TextOut(hdc, 280,300,s,strlen(s));
					 ok1=0;
					 ok2=0;
				 }
			break;
		  }
			
	
	   

	   if (LOWORD(wParam) == 2) {
              PostQuitMessage(0);
	   }
	
	   break;
	  }
	  
      /*case WM_PAINT:
		 {
		  hdc = BeginPaint(hwnd, &ps);
	
		
          EndPaint(hwnd, &ps);
		  }
          break;*/

      case WM_DESTROY:
          PostQuitMessage(0);
          break;
  }
 
  ReleaseDC(hwnd,hdc);
  return DefWindowProc(hwnd, msg, wParam, lParam);
}
HINSTANCE g_hinst;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow )
{
  //HWND hwnd;
  MSG  msg ;    
  WNDCLASS wc = {0};
  wc.lpszClassName = TEXT( "Graf" );
  wc.hInstance     = hInstance ;
  wc.hbrBackground = GetSysColorBrush(RGB(255,255,255));
  wc.lpfnWndProc   = WndProc ;
  wc.hCursor       = LoadCursor(0, IDC_ARROW);
  wc.lpszMenuName  = NULL;
  
  g_hinst = hInstance;
  RegisterClass(&wc);
  CreateWindow( wc.lpszClassName, TEXT("Graf"),
	  WS_EX_DLGMODALFRAME | WS_SYSMENU | WS_VISIBLE,
        400, 100, 600, 500, NULL, NULL, hInstance, NULL); 
  while( GetMessage(&msg, NULL, 0, 0)) {
      DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}

